package com.zhengxing.jienci.user.controller.rbac;

import com.google.common.collect.Maps;
import com.zhengxing.jienci.user.domain.rbac.Resource;
import com.zhengxing.jienci.user.domain.rbac.ResourceFunc;
import com.zhengxing.jienci.common.support.SimpleResponse;
import com.zhengxing.jienci.user.service.rbac.ResourceFuncService;
import com.zhengxing.jienci.user.service.rbac.ResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ResourceController
 *
 * @author philbert
 * @version 1.00
 */
@Slf4j
@RestController
@RequestMapping("/sys/resources")
@Lazy
public class ResourceController {

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private ResourceFuncService resourceFuncService;

    @GetMapping("loadResources")
    public List<Map<String, Object>> loadResources(String id) {
        return resourceService.findChildrenTreeNodes(id);
    }

    @GetMapping("")
    public SimpleResponse pagination(@RequestParam(value = "parentId", defaultValue = "0") String parentId,
                                     @RequestParam(value = "name", defaultValue = "") String name,
                                     @RequestParam(value = "code", defaultValue = "") String code,
                                     @RequestParam(value = "orderBy", defaultValue = "createdAt asc") String orderBy,
                                     @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                     @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        HashMap<String, Object> paramMap = Maps.newHashMap();
        try {
            parentId = URLDecoder.decode(parentId, StandardCharsets.UTF_8.toString());
            paramMap.put("parentId", parentId);
            name = URLDecoder.decode(name, StandardCharsets.UTF_8.toString());
            paramMap.put("name", name);
            code = URLDecoder.decode(code, StandardCharsets.UTF_8.toString());
            paramMap.put("code", code);
        } catch (UnsupportedEncodingException e) {
            log.error(e.getLocalizedMessage());
        }

        SimpleResponse simpleResponse = new SimpleResponse();
        simpleResponse.put("data", resourceService.getPagination(paramMap, orderBy, pageNo, pageSize));
        return simpleResponse;
    }

    @PostMapping("")
    public SimpleResponse save(@RequestBody Resource resource) {
        boolean bool = resourceService.save(resource);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @PatchMapping("{resourceId}")
    public SimpleResponse update(@PathVariable String resourceId, @RequestBody Resource resource) {
        resource.setCode(null); // 防止在页面通过修改html元素属性来达到修改资源代码的目的

        boolean bool = resourceService.update(resource);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @DeleteMapping("{resourceId}")
    public SimpleResponse delete(@PathVariable String resourceId) {
        boolean bool = resourceService.delete(resourceId);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @GetMapping("{resourceId}")
    public SimpleResponse view(@PathVariable String resourceId) {
        SimpleResponse simpleResponse = new SimpleResponse();
        simpleResponse.put("data", resourceService.get(resourceId));
        return simpleResponse;
    }

    @GetMapping("codeExist")
    public boolean codeExist(String code, String resourceId) {
        return !resourceService.codeExist(code, resourceId);
    }

    @GetMapping("{resourceId}/funcs")
    public SimpleResponse funcPagination(@PathVariable String resourceId,
                                         @RequestParam(value = "name", defaultValue = "") String name,
                                         @RequestParam(value = "code", defaultValue = "") String code,
                                         @RequestParam(value = "orderBy", defaultValue = "createdAt asc") String orderBy,
                                         @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                         @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        HashMap<String, Object> paramMap = Maps.newHashMap();
        try {
            resourceId = URLDecoder.decode(resourceId, StandardCharsets.UTF_8.toString());
            paramMap.put("resourceId", resourceId);
            name = URLDecoder.decode(name, StandardCharsets.UTF_8.toString());
            paramMap.put("name", name);
            code = URLDecoder.decode(code, StandardCharsets.UTF_8.toString());
            paramMap.put("code", code);
        } catch (UnsupportedEncodingException e) {
            log.error(e.getLocalizedMessage());
        }

        SimpleResponse simpleResponse = new SimpleResponse();
        simpleResponse.put("data", resourceFuncService.getPagination(paramMap, orderBy, pageNo, pageSize));
        return simpleResponse;
    }

    @PostMapping("{resourceId}/funcs")
    public SimpleResponse funcSave(@PathVariable String resourceId, @RequestBody ResourceFunc resourceFunc) {
        boolean bool = resourceFuncService.save(resourceFunc);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @PatchMapping("{resourceId}/funcs/{resourceFuncId}")
    public SimpleResponse funcUpdate(@PathVariable String resourceId, @PathVariable String resourceFuncId,
                                     @RequestBody ResourceFunc resourceFunc) {
        boolean bool = resourceFuncService.update(resourceFunc);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @DeleteMapping("{resourceId}/funcs/{resourceFuncId}")
    public SimpleResponse funcDelete(@PathVariable String resourceId, @PathVariable String resourceFuncId) {
        boolean bool = resourceFuncService.delete(resourceFuncId);
        if (bool) return SimpleResponse.success();
        else return SimpleResponse.fail();
    }

    @GetMapping("{resourceId}/funcs/{resourceFuncId}")
    public SimpleResponse funcView(@PathVariable String resourceId, @PathVariable String resourceFuncId) {
        SimpleResponse simpleResponse = new SimpleResponse();
        simpleResponse.put("data", resourceFuncService.get(resourceFuncId));
        return simpleResponse;
    }

    @GetMapping("{resourceId}/funcs/nameExist")
    public boolean funcNameExist(@PathVariable String resourceId, String name, String resourceFuncId) {
        return !resourceFuncService.nameExist(resourceId, name, resourceFuncId);
    }

    @GetMapping("{resourceId}/funcs/codeExist")
    public boolean funcCodeExist(@PathVariable String resourceId, String code, String resourceFuncId) {
        return !resourceFuncService.codeExist(resourceId, code, resourceFuncId);
    }

}
